package com.liwenfeng.diancanspringboot.common.utils;

import com.qcloud.cos.COSClient;
import com.qcloud.cos.ClientConfig;
import com.qcloud.cos.auth.BasicCOSCredentials;
import com.qcloud.cos.auth.COSCredentials;
import com.qcloud.cos.model.*;
import com.qcloud.cos.region.Region;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

@Data
@Slf4j
public class CosUtil {
    private String baseUrl;
    private String directory;
    private String secretId;
    private String secretKey;
    private String bucket;
    private String region;
    private COSClient cosClient;

    public CosUtil(String directory, String baseUrl, String secretId, String secretKey, String bucket, String region) {
        this.directory = directory == null ? "" : directory;
        this.baseUrl = baseUrl;
        this.secretId = secretId;
        this.secretKey = secretKey;
        this.bucket = bucket;
        this.region = region;
        this.cosClient = createCli();
    }

    private COSClient createCli() {
        // 初始化用户身份信息(secretId, secretKey)
        COSCredentials cred = new BasicCOSCredentials(secretId, secretKey);
        // 设置bucket的区域, COS地域的简称请参照 https://www.qcloud.com/document/product/436/6224
        ClientConfig clientConfig = new ClientConfig(new Region(region));
        // 生成cos客户端
        return new COSClient(cred, clientConfig);
    }

    /**
     * 上传文件
     */
    public String upload(MultipartFile file) {
        String filename = Objects.requireNonNull(file.getOriginalFilename());
        String extension = filename.substring(filename.lastIndexOf("."));
        log.info("上传文件扩展名：{}", extension);
        String random = Math.random() + "";
        String key = directory + System.currentTimeMillis() + "-" + random.substring(2, 5) + extension;
/*
        // 将上传图片保存到本地服务器的方法
        String uploadDir = "/var/www/static/";

        Path targetPath = Paths.get(uploadDir, file.getOriginalFilename());
        file.transferTo(targetPath);
        url= baseUrl + targetPath.toString();

        在WebMvcConfiguration.java文件中注册静态资源映射
        @Override
        public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/static/**")
               .addResourceLocations("file:" + uploadDir);
        }
 */

        ObjectMetadata objectMetadata = new ObjectMetadata();
        // 上传的流如果能够获取准确的流长度，则推荐一定填写 content-length
        // 如果确实没办法获取到，则下面这行可以省略，但同时高级接口也没办法使用分块上传了
        objectMetadata.setContentLength(file.getSize());

        PutObjectRequest putObjectRequest = null;
        try {
            putObjectRequest = new PutObjectRequest(bucket, key, file.getInputStream(), objectMetadata);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        // 设置单链接限速（如有需要），不需要可忽略
        putObjectRequest.setTrafficLimit(8 * 1024 * 1024);
        try {
            PutObjectResult putObjectResult = cosClient.putObject(putObjectRequest);
            log.info("上传完成，结果：{}{}", baseUrl, key);
            return baseUrl + key;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    // 删除
    public void delete(List<String> urls) {
        List<DeleteObjectsRequest.KeyVersion> keyVersions = urls.stream().map(url -> new DeleteObjectsRequest.KeyVersion(url.substring(baseUrl.length()))).toList();
        DeleteObjectsRequest deleteObjectsRequest = new DeleteObjectsRequest(bucket);
        deleteObjectsRequest.setKeys(keyVersions);
        cosClient.deleteObjects(deleteObjectsRequest);
    }

    // 查询cos中的文件列表
    public List<String> list() {
        ListObjectsRequest listObjectsRequest = new ListObjectsRequest();
        listObjectsRequest.setBucketName(bucket);
        listObjectsRequest.setPrefix(directory);
        listObjectsRequest.setMaxKeys(100);
        ObjectListing objectListing = null;
        List<String> urlList = new ArrayList<>();
        do {
            objectListing = cosClient.listObjects(listObjectsRequest);
            for (COSObjectSummary cosObjectSummary : objectListing.getObjectSummaries()) {
                String key = cosObjectSummary.getKey();
                if (!key.endsWith("/")) urlList.add(baseUrl + key);
            }
            listObjectsRequest.setMarker(objectListing.getNextMarker());

        } while (objectListing.isTruncated());
        return urlList;
    }

    // 清理无用图片
    public void clearUseless(List<String> urls) {
        List<String> cosUrls = list();
        List<String> list = cosUrls.stream().filter(url -> !urls.contains(url)).toList();
        log.info("cos中无用图片：{}", list);
        delete(list);
    }
}
